package controller

import (
	"encoding/json"
	"fmt"
	"mini-app/internal/app/grpc/common"
	"mini-app/internal/app/web/service"
	"mini-app/internal/define"
	"mini-app/internal/models"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/response"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type Order struct{}

// 创建订单
func (Order) CreateOrder(c *gin.Context) {
	var params struct {
		List           []service.CartRobotGoods `json:"list"`            // 商品列表
		Cart           int                      `json:"cart"`            // 是否为购物车
		PurchaseMethod int                      `json:"purchase_method"` // 购买方式 1-线下提货 2-快递到家
		UserAddress    models.UserAddress       `json:"user_address"`    // 收货地址

		// 核销方式 ""-默认线上支付(如微信或支付宝), "redemption_code"-兑换码支付
		ConsumeMethod define.ConsumeMethodDef `json:"consume_method"` // 核销方式
		Code          string                  `json:"code"`           // 兑换码

	}
	c.ShouldBindBodyWith(&params, binding.JSON)

	openid := c.GetString("openid")
	data, err := service.Order{}.CreateOrder(
		c.Request.Context(),
		openid,
		params.List,
		params.Cart,
		params.PurchaseMethod,
		params.UserAddress,
		params.ConsumeMethod,
		params.Code,
		0, // http接口默认 updateOrderStatus 为0，rpc接口提供该字段可配置
	)
	response.JSON(c, data, err)
}

// 兑换订单(使用兑换码) 2025-10-15 增加有价格的导流商品（原导流商品为免费），有价格的导流商品需要支付后使用兑换码
func (Order) RedeemOrder(c *gin.Context) {
	var params struct {
		ID string `json:"id"` // 订单ID
		//ConsumeMethod define.ConsumeMethodDef `json:"consume_method"` // 核销方式
		Code string `json:"code"` // 兑换码

	}
	err := c.ShouldBindBodyWith(&params, binding.JSON)
	if err != nil {
		response.JSON(c, nil, fmt.Errorf("解析参数错误: %s", err.Error()))
		return
	}

	if params.ID == "" || params.ID == "undefined" {
		response.JSON(c, nil, errorx.New(fmt.Sprintf("参数ID错误(%s)", params.ID), -1))
		return
	}

	openid := c.GetString("openid")
	err = service.Order{}.RedeemOrder(
		c.Request.Context(),
		openid,
		params.ID,
		params.Code,
	)
	response.JSON(c, nil, err)
}

// 获取订单列表
func (Order) OrderList(c *gin.Context) {
	var params struct {
		OrderStatus int      `json:"order_status"`
		Page        int      `json:"page"`
		Limit       int      `json:"limit"`
		GoodsIDs    []string `json:"goods_ids"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)

	openid := c.GetString("openid")
	list, total, err := service.Order{}.OrderList(c.Request.Context(), openid, params.OrderStatus,
		params.Page, params.Limit, params.GoodsIDs)
	response.JSON(c, gin.H{
		"total": total,
		"list":  list,
	}, err)
}

// 获取订单详情
func (Order) OrderDetail(c *gin.Context) {
	var params struct {
		ID string `json:"id"`
	}

	openid := c.GetString("openid")
	err := c.ShouldBindBodyWith(&params, binding.JSON)
	if err != nil {
		response.JSON(c, nil, errorx.New("解析参数错误", -1))
	}

	if params.ID == "" || params.ID == "0" {
		response.JSON(c, nil, errorx.New("参数错误", -1))
		return
	}

	if openid == "" || openid == "0" {
		response.JSON(c, nil, errorx.New("参数错误", -1))
		return
	}

	data, err := service.Order{}.OrderDetail(c.Request.Context(), openid, params.ID)
	response.JSON(c, data, err)
}

// 取货订单列表
func (Order) PickupOrders(c *gin.Context) {
	var params struct {
		SalesID string `json:"sales_id"` // 机器扫码支持sales_id
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	openid := c.GetString("openid")
	list, err := service.Order{}.PickupOrders(c.Request.Context(), openid, params.SalesID)
	response.JSON(c, list, err)
}

// 取货订单详情
func (Order) PickupOrderDetail(c *gin.Context) {
	var params struct {
		BatchID string `json:"batch_id"` // 订单批次号
	}
	c.ShouldBindBodyWith(&params, binding.JSON)

	openid := c.GetString("openid")
	data, err := service.Order{}.PickupOrderDetail(c.Request.Context(), openid, params.BatchID)
	response.JSON(c, data, err)
}

// 取货
func (Order) Pickup(c *gin.Context) {
	var params struct {
		BatchID string `json:"batch_id"` // 订单批次号
		RobotID string `json:"robot_id"` // 机器人ID
		GoodsID string `json:"goods_id"` // 商品ID
	}
	c.ShouldBindBodyWith(&params, binding.JSON)

	openid := c.GetString("openid")
	data, err := service.Order{}.Pickup(c.Request.Context(), c.RemoteIP(), openid, params.BatchID, params.RobotID, params.GoodsID)
	response.JSON(c, data, err)
}

// 零售平台获取购物车信息
func (Order) SaCartGoods(c *gin.Context) {
	var params struct {
		OrderID string `json:"order_id"` // 订单号
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	totalAmount, data, err := service.Order{}.SaCartGoods(c.Request.Context(), params.OrderID)
	response.JSON(c, gin.H{
		"total_amount": totalAmount,
		"list":         data,
	}, err)
}

// WechatJspay 零售调取微信的jsapi支付，返回相关参数供前端使用
func (Order) SaWechatJSPay(c *gin.Context) {
	var params struct {
		OrderID      string  `json:"order_id"`      // 订单号
		Points       float64 `json:"points"`        // 积分
		PointsID     string  `json:"points_id"`     // 积分类型
		PayUnivalent float64 `json:"pay_univalent"` // 积分类型
		MallCode     string  `json:"mall_code"`     // 积分类型
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	openid := c.GetString("openid")
	data, err := service.Order{}.SaWechatJSPay(c.Request.Context(), params.OrderID, openid, params.Points, params.PointsID, params.PayUnivalent, params.MallCode)
	response.JSON(c, data, err)
}

// WechatJspay 调取微信的jsapi支付，返回相关参数供前端使用
func (Order) WechatJSPay(c *gin.Context) {
	var params struct {
		OrderID      string  `json:"order_id"`      // 订单号
		Points       float64 `json:"points"`        // 积分
		PointsID     string  `json:"points_id"`     // 积分类型
		PayUnivalent float64 `json:"pay_univalent"` // 抵扣值
		MallCode     string  `json:"mall_code"`     // 商场ID

	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	openid := c.GetString("openid")
	data, err := service.Order{}.WechatJSPay(c.Request.Context(), params.OrderID, openid, params.Points, params.PointsID, params.PayUnivalent, params.MallCode)
	response.JSON(c, data, err)
}

// StatusStatistics 订单状态统计
func (Order) StatusStatistics(c *gin.Context) {
	data := service.Order{}.StatusStatistics(c.Request.Context(), c.GetString("openid"))
	response.JSON(c, data, nil)
}

func (Order) ShipmentInfo(c *gin.Context) {
	expressNum, expressCom := common.GRPC{}.OrderShipmentInfo(c.Request.Context(), c.Query("out_trade_no"))
	response.JSON(c, gin.H{
		"express_num": expressNum,
		"express_com": expressCom,
	}, nil)
}

func (Order) ShippingTracking(c *gin.Context) {
	var trackingList []interface{}
	list := common.GRPC{}.OrderShippingTracking(c.Request.Context(), c.Query("out_trade_no"))
	for _, record := range list {
		var recordJson interface{}
		json.Unmarshal([]byte(record), &recordJson)
		trackingList = append(trackingList, recordJson)
	}
	response.JSON(c, trackingList, nil)
}

func (Order) GetExpressFee(c *gin.Context) {
	var err error
	var params struct {
		GoodsID      string `json:"goods_id"`
		ProvinceName string `json:"province_name"`
	}
	params.GoodsID = c.Query("goods_id")
	params.ProvinceName = c.Query("province_name")
	if params.GoodsID == "" {
		err = errorx.New("商品id不能为空", -1)
	}
	if params.ProvinceName == "" {
		err = errorx.New("快递省份不能为空", -1)
	}
	if err != nil {
		response.JSON(c, nil, err)
		return
	}
	fee, err := common.GRPC{}.GetExpressFee(c.Request.Context(), params.GoodsID, params.ProvinceName)
	response.JSON(c, gin.H{
		"fee": fee,
	}, err)
}
